﻿using System;
using System.Collections.Generic;
using System.Text;

namespace FlashPay.Service.Impl
{
    using FlashPay.DAO.Interface;
    using FlashPay.EF;
    using FlashPay.EF.Models;
    using FlashPay.Entity.Request;
    using FlashPay.Entity.Response;
    using FlashPay.Entity.Response.DepositRecord;
    using FlashPay.Service.Interface;
    using FlashPay.Util;
    using Microsoft.EntityFrameworkCore;
    using System.Linq;
    using System.Web;

    public class QRCodeServiceImpl: QRCodeService
    {
        /// <summary>
        /// 上下文
        /// </summary>
        private FlashPayContext _context { set; get; }

        /// <summary>
        /// 上下文
        /// </summary>
        private DepositMatchRuleDao _depositMatchRuleDao { set; get; }
        

        /// <summary>
        /// 注入
        /// </summary>
        /// <param name="menu">菜单数据接口</param>
        /// <param name="menuPermission">菜单数据接口</param>
        public QRCodeServiceImpl(FlashPayContext context, DepositMatchRuleDao depositMatchRuleDao)
        {
            _context = context;
            _depositMatchRuleDao = depositMatchRuleDao;
        }

        /// <summary>
        /// 获取订单月份
        /// </summary>
        /// <param name="month"></param>
        /// <returns></returns>
        private string GetOrderMonth(long orderNo)
        {
            return orderNo.ToString().Substring(4, 2);
        }

        /// <summary>
        /// 根据订单编号获取
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public AlipayResponse GetAlipay(AlipayRequest request)
        {
            var response = new AlipayResponse();

            var tableName = $"DepositMatchRecord_{DateTime.Now.ToString("MM")}";

            if (!request.Id.HasValue) {
                throw new Exception("参数错误！");
            }

            if (request.Id.Value.ToString().Length != 18) {
                throw new Exception("订单号无效！");
            }

            var month = GetOrderMonth(request.Id.Value);

            if (month != DateTime.Now.ToString("MM"))
            {
                tableName = $"DepositMatchRecord_{month}";
            }

            #region 获取匹配记录
            var sql = $"SELECT * FROM {tableName} WHERE Id={request.Id}";

            var depositMatchRecord = _context.DepositMatchRecord
                .FromSql(sql)
                .AsNoTracking()
                .SingleOrDefault();

            if (depositMatchRecord == null)
            {
                throw new Exception("订单不存在！");
            }

            if (depositMatchRecord.MatchOrderNo.HasValue) {
                throw new Exception("订单已支付！");
            }

            response.Amount = depositMatchRecord.DepositAmount;
            #endregion

            #region 获取银行卡记录
            var bankCard = _context.BankCard.FirstOrDefault(c => c.CardNumber == depositMatchRecord.DepositCardNumber);
            if (bankCard == null)
            {
                throw new Exception("收款卡不存在！");
            }

            if (string.IsNullOrEmpty(bankCard.AliPayCardName) || string.IsNullOrEmpty(bankCard.AliPayBankMark) || string.IsNullOrEmpty(bankCard.AliPayCardIndex)) {
                throw new Exception("未绑定银行卡！");
            }
            #endregion

            #region 获匹配规则
            var depositMatchRule = _depositMatchRuleDao.GetRuleByCompanyId(new DepositMatchRule()
            {
                CompanyId = depositMatchRecord.CompanyId,
                MatchBankCode = depositMatchRecord.BankCode,
                MatchTranstype = depositMatchRecord.Transtype.ToString()
            });

            var now = DateTime.Now;

            var depositMatchTime = depositMatchRecord.DepositDate;

            if (depositMatchRule == null || depositMatchRule.MatchMinute <= 0){
                depositMatchTime = depositMatchTime.AddMinutes(5);
            }
            else {
                depositMatchTime = depositMatchTime.AddMinutes(depositMatchRule.MatchMinute);
            }

            if (DateTime.Compare(depositMatchTime, now) > 0){
                response.Seconds = (int)depositMatchTime.Subtract(now).TotalSeconds;
            }
            else {
                throw new Exception("支付时间已过期！");
            }
            #endregion

            #region 请求参数
            //请求Uri
            var requestUrl = "https://www.alipay.com/?";
            //参数
            var paras = new Dictionary<String, String>();
            paras.Add("appId", "09999988");
            paras.Add("actionType", "toCard");
            paras.Add("sourceId", "bill");
            paras.Add("cardNo", "请勿修改金额,三分钟内到账***");
            paras.Add("bankAccount", HttpUtility.UrlEncode(bankCard.CardName, Encoding.UTF8));
            paras.Add("receiverName", HttpUtility.UrlEncode(bankCard.CardName, Encoding.UTF8));
            paras.Add("money", depositMatchRecord.DepositAmount.ToString("0.##"));
            paras.Add("amount", depositMatchRecord.DepositAmount.ToString("0.##"));
            paras.Add("bankMark", bankCard.AliPayBankMark);
            paras.Add("cardIndex", bankCard.AliPayCardIndex);
            paras.Add("cardNoHidden", "true");
            paras.Add("cardChannel", "HISTORY_CARD");
            paras.Add("orderSource", "from");
            response.RequestUrl = WebUtil.buildParamStr(requestUrl, paras);
            #endregion

            return response;
        }

        /// <summary>
        /// 根据订单编号获取
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public DepositRecordResponse GetDepositRecord(AlipayRequest request)
        {
            var response = new DepositRecordResponse();

            var tableName = $"DepositMatchRecord_{DateTime.Now.ToString("MM")}";

            if (!request.Id.HasValue)
            {
                throw new Exception("参数错误！");
            }

            if (request.Id.Value.ToString().Length != 18)
            {
                throw new Exception("订单号无效！");
            }

            var month = GetOrderMonth(request.Id.Value);

            if (month != DateTime.Now.ToString("MM"))
            {
                tableName = $"DepositMatchRecord_{month}";
            }

            #region 获取匹配记录
            var sql = $"SELECT * FROM {tableName} WHERE ClientOrderNo='{request.OrderNo}' And Id={request.Id.Value}";

            var depositMatchRecord = _context.DepositMatchRecord
                .FromSql(sql)
                .AsNoTracking()
                .SingleOrDefault();

            if (depositMatchRecord == null)
            {
                throw new Exception("订单不存在！");
            }

            if (depositMatchRecord.MatchOrderNo.HasValue)
            {
                throw new Exception("订单已支付！");
            }

            if (depositMatchRecord.Transtype.HasValue) {
                var config = _context.SysConfig.FirstOrDefault(c => c.ConfigCode == "Transtype" && c.ConfigValue == depositMatchRecord.Transtype);
                if (config != null)
                {
                    response.TransType = config.ConfigContent;
                }
            }

            response.DepositName = depositMatchRecord.ClientAccountName;
            response.DepositAmount = depositMatchRecord.DepositAmount.ToString("0.##");
            #endregion

            #region 获取银行卡记录
            var bankCard = _context.BankCard.FirstOrDefault(c => c.CardNumber == depositMatchRecord.DepositCardNumber);
            if (bankCard == null)
            {
                throw new Exception("收款卡不存在！");
            }

            response.ReceiptBankName = bankCard.BankName;
            response.ReceiptCardNumber = bankCard.CardNumber;
            response.ReceiptName = bankCard.CardName;
            #endregion

            #region 获匹配规则
            var depositMatchRule = _depositMatchRuleDao.GetRuleByCompanyId(new DepositMatchRule()
            {
                CompanyId = depositMatchRecord.CompanyId,
                MatchBankCode = depositMatchRecord.BankCode,
                MatchTranstype = depositMatchRecord.Transtype.ToString()
            });

            var now = DateTime.Now;

            var depositMatchTime = depositMatchRecord.DepositDate;

            if (depositMatchRule == null || depositMatchRule.MatchMinute <= 0)
            {
                depositMatchTime = depositMatchTime.AddMinutes(5);
            }
            else
            {
                depositMatchTime = depositMatchTime.AddMinutes(depositMatchRule.MatchMinute);
            }

            if (DateTime.Compare(depositMatchTime, now) > 0)
            {
                response.Seconds = (int)depositMatchTime.Subtract(now).TotalSeconds;
            }
            else
            {
                throw new Exception("支付时间已过期！");
            }
            #endregion

            return response;
        }
    }
}
